package org.codefinger.dao.impl.mssql;

import javax.sql.DataSource;

import org.codefinger.dao.impl.Querier;
import org.codefinger.dao.impl.QueryParam;
import org.codefinger.dao.impl.SQLVisitor;
import org.codefinger.dao.impl.sql.Column;
import org.codefinger.dao.impl.sql.Group;
import org.codefinger.dao.impl.sql.Having;
import org.codefinger.dao.impl.sql.Join;
import org.codefinger.dao.impl.sql.Order;
import org.codefinger.dao.impl.sql.Source;
import org.codefinger.dao.impl.sql.Union;
import org.codefinger.dao.impl.sql.Where;

public class SQLServerQuerier extends Querier {

	public SQLServerQuerier(//
			DataSource dataSource,//
			boolean isDistinct, //
			Column column, //
			Source from, //
			Join join,//
			Where where, //
			Group group, //
			Having having, //
			Union union, //
			Order order,//
			String[] aliases) {

		super(dataSource,//
				isDistinct,//
				column, //
				from, //
				join, //
				where, //
				group, //
				having,//
				union, //
				order,//
				aliases);
	}

	@Override
	protected SQLVisitor visitPaging(QueryParam queryParam) {
		int pageIndex = queryParam.getPageIndex();
		if (pageIndex < 1) {
			pageIndex = 1;
		}
		int pageSize = queryParam.getPageSize();
		if (pageSize < 0) {
			pageSize = 0;
		}
		int max = pageIndex * pageSize;

		SQLVisitor visitor = new SQLVisitor(queryParam);
		if (union == null) {
			if (isDistinct) {
				visitor.appendSQL("SELECT * FROM (SELECT ALL_CONTENT.*,ROW_NUMBER()OVER(ORDER BY(SELECT 0)) ROW_NUMBER FROM (SELECT DISTINCT TOP ");
			} else {
				visitor.appendSQL("SELECT * FROM (SELECT ALL_CONTENT.*,ROW_NUMBER()OVER(ORDER BY(SELECT 0)) ROW_NUMBER FROM (SELECT TOP ");
			}
			visitor.appendSQL(Integer.toString(max));
			visitor.appendSQL(' ');
			column.visitAlias(visitor);
			from.visit(visitor);
			if (join != null) {
				join.visit(visitor);
			}
			if (where != null) {
				where.visit(visitor);
			}
			if (group != null) {
				group.visit(visitor);
			}
			if (having != null) {
				having.visit(visitor);
			}
			if (order != null) {
				order.visit(visitor);
			}
			visitor.appendSQL(") ALL_CONTENT) ALL_CONTENT WHERE ALL_CONTENT.ROW_NUMBER > ");
			visitor.appendSQL(Integer.toString(max - pageSize));
		} else {
			visitor.appendSQL("SELECT * FROM (SELECT ALL_CONTENT.*,ROW_NUMBER()OVER(ORDER BY(SELECT 0)) ROW_NUMBER FROM (SELECT TOP ");
			visitor.appendSQL(Integer.toString(max));
			visitor.appendSQL(" ALL_CONTENT.* FROM (SELECT ");
			if (isDistinct) {
				visitor.appendSQL("DISTINCT ");
			}
			column.visitAlias(visitor);
			from.visit(visitor);
			if (join != null) {
				join.visit(visitor);
			}
			if (where != null) {
				where.visit(visitor);
			}
			if (group != null) {
				group.visit(visitor);
			}
			if (having != null) {
				having.visit(visitor);
			}
			union.visit(visitor);
			visitor.appendSQL(") ALL_CONTENT");
			if (order != null) {
				order.visit(visitor);
			}
			visitor.appendSQL(") ALL_CONTENT) ALL_CONTENT WHERE ALL_CONTENT.ROW_NUMBER > ");
			visitor.appendSQL(Integer.toString(max - pageSize));
		}
		return visitor;
	}

}
